using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;

namespace UniversalAdmin.Application.Services;

public class ChatHistoryService : IChatHistoryService
{
    private readonly IChatHistoryRepository _chatHistoryRepository;
    private readonly IDocumentRepository _documentRepository;

    public ChatHistoryService(
        IChatHistoryRepository chatHistoryRepository,
        IDocumentRepository documentRepository)
    {
        _chatHistoryRepository = chatHistoryRepository;
        _documentRepository = documentRepository;
    }

    public async Task<ChatHistoryDto> CreateChatHistoryAsync(CreateChatHistoryDto dto)
    {
        var chatHistory = new ChatHistory
        {
            UserId = dto.UserId,
            SessionId = dto.SessionId,
            Question = dto.Question,
            Answer = dto.Answer,
            CreatedAt = DateTime.UtcNow
        };

        // 添加关联文档
        if (dto.RelatedDocumentIds != null && dto.RelatedDocumentIds.Any())
        {
            foreach (var documentId in dto.RelatedDocumentIds)
            {
                // 验证文档是否存在
                var document = await _documentRepository.GetByIdAsync(documentId);
                if (document != null)
                {
                    chatHistory.ChatDocuments.Add(new ChatDocument
                    {
                        DocumentId = documentId,
                        RelevanceScore = dto.RelevanceScores?.FirstOrDefault(s => s.DocumentId == documentId)?.Score ?? 0
                    });
                }
            }
        }

        await _chatHistoryRepository.AddAsync(chatHistory);
        return MapToDto(chatHistory);
    }

    public async Task<ChatHistoryDto?> GetChatHistoryByIdAsync(Guid id)
    {
        var chatHistory = await _chatHistoryRepository.GetByIdAsync(id);
        return chatHistory != null ? MapToDto(chatHistory) : null;
    }

    public async Task<PagedResultDto<ChatHistoryDto>> GetChatHistoriesByUserIdAsync(Guid userId, int page = 1, int pageSize = 10)
    {
        var result = await _chatHistoryRepository.GetByUserIdPagedAsync(userId, page, pageSize);
        return new PagedResultDto<ChatHistoryDto>
        {
            TotalCount = result.TotalCount,
            Items = result.Items.Select(MapToDto).ToList()
        };
    }

    public async Task<IEnumerable<ChatHistoryDto>> GetChatHistoriesBySessionIdAsync(string sessionId)
    {
        var chatHistories = await _chatHistoryRepository.GetBySessionIdAsync(sessionId);
        return chatHistories.Select(MapToDto);
    }

    public async Task<ChatHistoryDto?> GetLatestChatHistoryBySessionIdAsync(string sessionId)
    {
        var chatHistory = await _chatHistoryRepository.GetLatestBySessionIdAsync(sessionId);
        return chatHistory != null ? MapToDto(chatHistory) : null;
    }

    public async Task<IEnumerable<ChatHistoryDto>> SearchChatHistoriesAsync(Guid userId, string keyword)
    {
        var chatHistories = await _chatHistoryRepository.SearchAsync(userId, keyword);
        return chatHistories.Select(MapToDto);
    }

    public async Task<bool> DeleteChatHistoryByIdAsync(Guid id)
    {
        var chatHistory = await _chatHistoryRepository.GetByIdAsync(id);
        if (chatHistory == null)
            return false;

        await _chatHistoryRepository.DeleteAsync(chatHistory);
        return true;
    }

    public async Task<bool> DeleteChatHistoriesBySessionIdAsync(string sessionId)
    {
        return await _chatHistoryRepository.DeleteBySessionIdAsync(sessionId);
    }

    public async Task<int> GetSessionCountByUserIdAsync(Guid userId)
    {
        return await _chatHistoryRepository.GetSessionCountByUserIdAsync(userId);
    }

    private ChatHistoryDto MapToDto(ChatHistory chatHistory)
    {
        return new ChatHistoryDto
        {
            Id = chatHistory.Id,
            UserId = chatHistory.UserId,
            SessionId = chatHistory.SessionId,
            Question = chatHistory.Question,
            Answer = chatHistory.Answer,
            CreatedAt = chatHistory.CreatedAt,
            RelatedDocuments = chatHistory.ChatDocuments.Select(cd => new RelatedDocumentDto
            {
                DocumentId = cd.DocumentId,
                RelevanceScore = cd.RelevanceScore
            }).ToList()
        };
    }
}